﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AAA.Finacial.Indicator
{
    public class TechnicalIndex
    {

        public static float RSV(List<float> lstClose, List<float> lstHigh, List<float> lstLow, int iStartIndex, int iLen)
        {
            if (lstClose.Count < iStartIndex + iLen)
                return float.NaN;
            
            float fHighest = -float.MaxValue;
            float fLowest = float.MaxValue;            

            try
            {
                for (int i = 0; i < iLen; i++)
                {
                    fHighest = Math.Max(lstHigh[iStartIndex + i], fHighest);
                    fLowest = Math.Min(lstLow[iStartIndex + i], fLowest);
                }

                return (fHighest != fLowest)
                            ? (lstClose[iStartIndex + iLen - 1] - fLowest) / (fHighest - fLowest) * 100
                            : float.NaN;
            }
            catch (Exception ex)
            {
            }

            return float.NaN;
        }

        public static float Highest(List<float> lstValue, int iLen)
        {
            return Highest(lstValue, (int)Math.Max(0, lstValue.Count - iLen), iLen);
        }

        public static float Highest(List<float> lstValue, int iStartIndex, int iLen)
        {
            if (lstValue.Count < iStartIndex + iLen)
                return float.NaN;

            float fHighest = 0;

            for (int i = 0; i < iLen; i++)
            {
                if (float.IsNaN(lstValue[iStartIndex + i]) ||
                    float.IsInfinity(lstValue[iStartIndex + i]))
                    continue;
                fHighest = (float)Math.Max(fHighest, lstValue[iStartIndex + i]);

            }
            return fHighest;
        }

        public static float Lowest(List<float> lstValue, int iLen)
        {
            return Lowest(lstValue, (int)Math.Max(0, lstValue.Count - iLen), iLen);
        }

        public static float Lowest(List<float> lstValue, int iStartIndex, int iLen)
        {
            if (lstValue.Count < iStartIndex + iLen)
                return float.NaN;

            float fLowest = float.MaxValue;

            for (int i = 0; i < iLen; i++)
            {
                if (float.IsNaN(lstValue[iStartIndex + i]) ||
                    float.IsInfinity(lstValue[iStartIndex + i]))
                    continue;
                fLowest = (float)Math.Min(fLowest, lstValue[iStartIndex + i]);

            }
            return fLowest;
        }

        public static float MA(List<float> lstValue, int iLen)
        {
            return MA(lstValue, (int)Math.Max(0, lstValue.Count - iLen), iLen);
        }

        public static float MA(List<float> lstValue, int iStartIndex, int iLen)
        {
            if (lstValue.Count < iStartIndex + iLen)
                return float.NaN;

            try
            {
                float fSum = 0;
                int iCount = iLen;

                for (int i = 0; i < iLen; i++)
                {
                    if (float.IsNaN(lstValue[iStartIndex + i]) ||
                       float.IsInfinity(lstValue[iStartIndex + i]))
                    {
                        iCount--;
                    }
                    else
                    {
                        fSum += lstValue[iStartIndex + i];
                    }
                }

                return iCount == 0 ? float.NaN : fSum / (float)iCount;
            }
            catch (Exception ex)
            {

            }
            return float.NaN;
        }

    }
}
